
#ifndef _DRV_SDB_H_
#define _DRV_SDB_H_

#ifdef __cplusplus
extern "C" {
#endif

#define DRV_SER_GRANULARITY   10000   /* ns*/

#define DRV_MEM_ENTRY_SIZE(lchip, mem_id)   (DRV_MEM_INFO(lchip, mem_id).entry_size)
#define DRV_MEM_ADDR_SEL(lchip, mem_id)     (DRV_MEM_INFO(lchip, mem_id).addr_sel)

#define DRV_SDB_DB(lchip)           (g_sdb_master[lchip])
#define DRV_TBL_TCAM_MEM(tbl_id)    TABLE_INFO(lchip, tbl_id).tcam_mem
#define DRV_TBL_FEA_MOD(tbl_id)    TABLE_INFO(lchip, tbl_id).fea_mod
#define DRV_SDB_MODE(tbl_id)        TABLE_INFO(lchip, tbl_id).sdb_type
#define DRV_SDB_READ(tbl_id)        TABLE_INFO(lchip, tbl_id).sdb_read
#define DRV_SDB_MODE_VALID(tbl_id)  (DRV_SDB_MODE(tbl_id) != SDB_DIS && DRV_SDB_MODE(tbl_id) <= p_drv_master[lchip]->sdb_type)

#define DRV_SDB_TBL_ID_SIZE 2
#define DRV_SDB_LPM_TCAM_BLOCK_NUM 4
#define DRV_SDB_LPM_AD_BLOCK_NUM 2
#define DRV_SDB_LPM_KEY_BLOCK_NUM 4
#define DRV_SDB_MPLS_HS_KEY_ECC_SIZE  64
#define DRV_SDB_SHARE_BUFFER_ECC_SIZE 48
#define DRV_SDB_ADDR_BASE(tbl_id)       g_sdb_master[lchip]->static_tbl[tbl_id]
#define DRV_SDB_TS_SIZE         sizeof(uint32)
#define DRV_SDB_MIN_TBL_SIZE    sizeof(uint32)
#define DRV_SDB_ENT_TS_PTR(tbl_id, p_ts_hdr, entry_idx) ((uint8*)DRV_SDB_ADDR_BASE(tbl_id) + p_ts_hdr->ent_ts_offset + DRV_SDB_TS_SIZE * entry_idx)
#define DRV_SDB_ENTRY_SIZE_ALINE(entry_size, entry_offset) \
    if (entry_size <= 4) {\
        entry_offset = 4;\
    } else if (entry_size <= 8) {\
        entry_offset = 8;\
    } else if (entry_size <= 16) {\
        entry_offset = 16;\
    } else if (entry_size <= 32) {\
        entry_offset = 32;\
    } else if (entry_size <= 64) {\
        entry_offset = 64;\
    } else {\
        entry_offset = 128;\
    }
#define DRV_SDB_TCAM_DMCHK(p_sw_buffer, entry_size_per_index)    \
{\
    uint32 _word_offset_ = 0;\
    uint32* _p_mask_ = (uint32*)((uint8*)(p_hw_buffer) + (entry_size_per_index));\
    do {\
        (p_sw_buffer)[_word_offset_] = (_p_mask_[_word_offset_] & (p_sw_buffer)[_word_offset_]);\
    }while(++_word_offset_ < ((entry_size_per_index)>>2));\
}
#define DRV_SDB_TCAM_XY2DM(p_hw_buffer, entry_size_per_index)    \
{\
    uint32 _mask_tmp_ = 0;\
    uint32 _word_offset_ = 0;\
    uint32* _p_mask_ = (uint32*)((uint8*)(p_hw_buffer) + (entry_size_per_index));\
    do {\
        _mask_tmp_ = (_p_mask_[_word_offset_] ^ (p_hw_buffer)[_word_offset_]);\
        (p_hw_buffer)[_word_offset_] = (_mask_tmp_ & (p_hw_buffer)[_word_offset_]);\
        _p_mask_[_word_offset_] = _mask_tmp_;\
    }while(++_word_offset_ < ((entry_size_per_index)>>2));\
}
/*update for bit revert*/
#define DRV_SDB_TCAM_DM2XY(p_hw_buffer, entry_size_per_index)    \
{\
    uint32 _data_tmp_ = 0;\
    uint32 _word_offset_ = 0;\
    uint32* _p_data_ = (uint32*)((uint8*)(p_hw_buffer) + (entry_size_per_index));\
    do {\
        _data_tmp_ = (_p_data_[_word_offset_] & (p_hw_buffer)[_word_offset_]);\
        (p_hw_buffer)[_word_offset_] = _data_tmp_ ^ (p_hw_buffer)[_word_offset_];\
        _p_data_[_word_offset_] = _data_tmp_;\
    }while(++_word_offset_ < ((entry_size_per_index)>>2));\
}

#define DRV_SDB_PTR(lchip)  (g_sdb_master[lchip])

#define DRV_READ_MEM_FROM_SER(tbl_id)   (DRV_SDB_DB(lchip) && DRV_SDB_ADDR_BASE(tbl_id) != 0  && DRV_SDB_READ(tbl_id) && (!DRV_SDB_DB(lchip)->read_tbl_from_hw  \
    || (SDB_MEM_MODEL == SDB_MODE)))


enum drv_ser_db_recover_mode_e
{
    DRV_SDB_RECOVER_STATIC_TBL,
    DRV_SDB_RECOVER_DYNAMIC_TBL,
    DRV_SDB_RECOVER_TCAM_KEY,
    DRV_SDB_RECOVER_ALL,
    DRV_SDB_RECOVER_MAX_NUM
};
typedef enum drv_ser_db_recover_mode_e drv_ser_db_recover_mode_t;


struct drv_ser_db_dma_rw_s
{
    uint32  tbl_addr;
    uint32* buffer;

    uint16  entry_num;
    uint16  entry_len;

    uint8   rflag;
    uint8   is_pause;
    uint8   user_dma_mode; /*use the user alloced dma memory*/
    uint8   rsv;
};
typedef struct drv_ser_db_dma_rw_s drv_ser_db_dma_rw_t;


struct drv_ser_db_err_mem_info_s
{
   uint8  err_mem_type;
   uint8  err_mem_order;
   uint32 err_mem_offset;
   uint32 err_entry_size;
};
typedef struct drv_ser_db_err_mem_info_s drv_ser_db_err_mem_info_t;

 /*#include "drv_api.h"*/
enum drv_ser_db_mask_tcam_fld_type_e
{
    DRV_SDB_MASK_TCAM_BY_STORE,
    DRV_SDB_MASK_TCAM_BY_READ,
    DRV_SDB_MASK_TCAM_BY_INIT,
    DRV_MEM_DB_MASK_TCAM_FOR_DMA,
    DRV_SDB_MASK_TCAM_MAX_NUM
};
typedef enum drv_ser_db_mask_tcam_fld_type_e drv_ser_db_mask_tcam_fld_type_t;

struct drv_ser_db_mask_tcam_fld_s
{
   uint8  type; /*drv_ser_db_mask_tcam_fld_type_t*/
   uint8  ram_id;
   uint8  entry_valid;
   uint32* p_data;
   uint32* p_mask;
};
typedef struct drv_ser_db_mask_tcam_fld_s drv_ser_db_mask_tcam_fld_t;

struct drv_sdb_ts_hdr_s
{
    uint32 tbl_ts;
    uint32 ent_ts_offset;
};
typedef struct drv_sdb_ts_hdr_s drv_sdb_ts_hdr_t;

typedef int32 (* mem_db_traversal_fn)(void* bucket_data, void* user_data);
typedef int32 (*hash_traverse_cb)(void* p_data1, mem_db_traversal_fn traverse_fn, void* p_data2);
typedef int32 (*drv_sdb_write_cb)(uint8 lchip, tbls_id_t tbl_id, uint32 index, void* p_data, uint32 entry_size);
typedef int32 (*drv_sdb_req_cache_cb)(uint8 lchip, uint32 entry_size, uint32* cache_addr);
typedef int32 (*drv_sdb_build_dma_desc_cb)(uint8 lchip, uint32 hw_addr, uint32 cache_addr, uint32 entry_size);
typedef int32 (*drv_sdb_io_cache_cb)(uint8 lchip, uintptr addr, uint32* data, int32 len);

#define DRV_SDB_DMA_BUCKET_NUM (16)
#define DRV_SDB_DMA_INVALID_DESC_IDX 0xFFFF
#define DRV_SDB_DMA_TRIGGER_DESC_NUM (4)

struct drv_sdb_s
{

    uint8*      static_tbl[MaxTblId_t];
    uint8*      dynamic_tbl[DRV_FTM_MAX_ID];
    uint32      dma_scan_timestamp[DRV_FTM_MAX_ID][2];/*for dma tcam scan*/
    uint32*     p_reset_hw_alloc_mem[2];/*0:malloc normal cpu memory; 1:malloc dma memory*/

    uintptr     mem_addr;                     /**<  the start memory address of SDB */
    uint32      mem_size;                     /**<  the memory size of SDB */
    uint32      catch_mem_static_size;
    uint32      catch_mem_dynamic_size;
    uint32      catch_mem_tcam_key_size;

    uint32      sdb_en              :1;          /*overall control */
    uint32      hw_reset_status     :1;
    uint32      read_tbl_from_hw    :1;
    uint32      pmem_en             :1;
    uint32      restore_tbl_from_hw :1;
    uint32      rsv                 :27;
    drv_ser_hw_reset_cb  reset_hw_cb[DRV_SER_HW_RESET_CB_TYPE_NUM];
    drv_ser_get_data_memory_cb get_dma_data_memory_cb;

    DRV_DMA_WRITE_CB  dma_write_cb;
    DRV_DMA_READ_CB  dma_read_cb;
    DRV_DMA_WAIT_DESC_DONE_CB  dma_wait_done_cb;
    DRV_DMA_TRIGGER_CB dma_trigger_cb;
    uint32*     dma_mem_bucket[DRV_SDB_DMA_BUCKET_NUM];
    uint16      desc_index_map[DRV_SDB_DMA_BUCKET_NUM]; /*per dma bucket mapped desc index, 0xFFFF is not used*/
    uint16      dma_mem_idx;
};
typedef struct drv_sdb_s drv_sdb_t;

extern drv_sdb_t* g_sdb_master[DRV_MAX_CHIP_NUM];

extern int32
drv_usw_chip_write_sram_entry(uint8 lchip, uint64 addr, uint32* data, int32 len);
extern int32
drv_usw_chip_write_sram_entry2(uint8 lchip, uint64 addr, uint32* data, int32 len);

extern int32
drv_sdb_deinit(uint8 lchip);
extern int32
drv_sdb_set_hw_reset_en(uint8 lchip, uint8 enable);

extern int32
drv_sdb_rewrite_tcam(uint8 lchip, uint8 mem_id, uint8 mem_type, uint8 mem_order, uint32 entry_idx, void* p_tbl_entry);

extern int32
drv_sdb_map_lpm_tcam(uint8 lchip, uint8* p_mem_id, uint8* p_mem_order, uint16* p_entry_idx);

extern int32
drv_sdb_unmap_lpm_tcam(uint8 lchip, uint8* p_mem_id, uint8* p_mem_order, uint16* p_entry_idx);

extern int32
drv_sdb_get_tcam_local_entry_size(uint8 lchip, uint8 mem_id, uint32*p_entry_size);

extern int32
drv_ser_check_correct_tcam(uint8 lchip, uint32 mem_id, uint32 tbl_idx, void* p_void, uint8 rd_empty);
extern uint8
_drv_sdb_get_ram_type(uint8 lchip, uint8 ram_id, uint8 is_detail);

extern void*
drv_sdb_read(uint8 lchip, tbls_id_t tbl_id, uint32 index, uint32 entry_size, uint8 oper_bmp);
extern int32
drv_sdb_write(uint8 lchip, tbls_id_t tbl_id, uint32 entry_idx, void* p_data, uint32 entry_size, uint8 oper_bmp);
extern int32
drv_sdb_store(uint8 lchip, tbls_id_t tbl_id, uint32 entry_idx, void* p_data, uint32 entry_size, uint8 oper_bmp);
extern int32
drv_sdb_check_per_ram(uint8 lchip, uint8 mem_id, uint8 recover_en, uint8* cmp_result, sal_file_t pf);
extern uint32
drv_sdb_get_sdb_en(uint8 lchip);

#ifdef __cplusplus
}
#endif

#endif
